#include	"../core/router.h"
#include    "../utils/logger.h"

extern "C" {
#include	<luajit.h>
#include	<lualib.h>
#include	<lauxlib.h>
}

namespace {

    static int Any(lua_State * lua) {
        if (!lua_isuserdata(lua, 1)) {
			Logger::Instance().Error("Please using router:any() instead of router.any()");
			return 0;
		}

        Router * router = *(Router **)lua_topointer(lua, 1);
        std::string pattern = lua_tostring(lua, 2);

        lua_pushvalue(lua, 3);
        int proc_ref = luaL_ref(lua, LUA_REGISTRYINDEX);
        router->Any(pattern, proc_ref);

        return 0;
    }

    static int Get(lua_State * lua) {
        if (!lua_isuserdata(lua, 1)) {
			Logger::Instance().Error("Please using router:get() instead of router.get()");
			return 0;
		}

        Router * router = *(Router **)lua_topointer(lua, 1);
        std::string pattern = lua_tostring(lua, 2);

        lua_pushvalue(lua, 3);
        int proc_ref = luaL_ref(lua, LUA_REGISTRYINDEX);
        router->Get(pattern, proc_ref);

        return 0;
    }

    static int Post(lua_State * lua) {
        if (!lua_isuserdata(lua, 1)) {
			Logger::Instance().Error("Please using router:post() instead of router.post()");
			return 0;
		}

        Router * router = *(Router **)lua_topointer(lua, 1);
        std::string pattern = lua_tostring(lua, 2);

        lua_pushvalue(lua, 3);
        int proc_ref = luaL_ref(lua, LUA_REGISTRYINDEX);
        router->Post(pattern, proc_ref);

        return 0;
    }
}

void RegisterApi_Router(lua_State * lua) {
    luaL_newmetatable(lua, "__omni_router");
	lua_pushvalue(lua, -1);
	lua_setfield(lua, -2, "__index");

	lua_pushcfunction(lua, &Get);
	lua_setfield(lua, -2, "get");

	lua_pushcfunction(lua, &Post);
	lua_setfield(lua, -2, "post");

	lua_pushcfunction(lua, &Any);
	lua_setfield(lua, -2, "any");

	lua_pop(lua, 1);
}